package cn.kwq.project_manger.service.impl;

import cn.kwq.project_manger.pojo.JoinTeam;
import cn.kwq.project_manger.pojo.QJoinTeam;
import cn.kwq.project_manger.pojo.QTeam;
import cn.kwq.project_manger.pojo.QTeamUser;
import cn.kwq.project_manger.pojo.dto.ResJoinTeamDTO;
import cn.kwq.project_manger.repostitory.JoinTeamRepository;
import cn.kwq.project_manger.service.JoinTeamService;
import cn.kwq.project_manger.service.ResumeService;
import com.querydsl.jpa.impl.JPAQueryFactory;
import lombok.extern.slf4j.Slf4j;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;

import java.util.Objects;
import java.util.stream.Collectors;

import static org.springframework.transaction.annotation.Isolation.REPEATABLE_READ;

@Service
@Slf4j
public class JoinTeamServiceImpl implements JoinTeamService {

    @Autowired
    JoinTeamRepository joinTeamRepository;

    @Autowired
    JPAQueryFactory jpaQueryFactory;

    @Autowired
    ResumeService resumeService;

    final Object lock = new Object();

    @Override
    @Transactional
    public List<JoinTeam> applyJoin(Long teamId, Long userId) {
        QTeamUser teamUser=QTeamUser.teamUser;
        //检查是否重复申请
        QJoinTeam joinTeam=QJoinTeam.joinTeam;
        JoinTeam check = jpaQueryFactory.selectFrom(joinTeam)
                .where(joinTeam.teamId.eq(teamId))
                .where(joinTeam.joinUserId.eq(userId))
                .fetchOne();
        if (check!=null&&check.getJoinUserId()!=null){
            if (check.getIsMembers()!=null && check.getIsMembers()==0){
                log.error("人员["+userId+"] 申请 ["+teamId+"]队伍已被拒绝过");
                throw new RuntimeException("您已被该队伍拒绝过");
            }
            log.error("人员["+userId+"] 重复申请 ["+teamId+"]队伍");
            throw new RuntimeException("请勿重复申请加入该队伍");
        }

        //该队队长的id
        Long captionId = jpaQueryFactory.select(teamUser.UserId)
                .from(teamUser)
                .where(teamUser.isCaption.eq(1))
                .where(teamUser.teamId.eq(teamId))
                .fetchOne();

        if (Objects.equals(captionId, userId)){
            log.error("人员["+userId+"] 是 ["+teamId+"]队伍的队长，不可申请");
            throw new RuntimeException("人员["+userId+"] 是 ["+teamId+"]队伍的队长，不可申请");
        }

        joinTeamRepository.save(JoinTeam
                .builder()
                .joinUserId(userId)
                .captionUserId(captionId)
                .teamId(teamId)
                .build());




        return jpaQueryFactory.selectFrom(joinTeam)
                .where(joinTeam.teamId.eq(teamId))
                .fetch();
    }

    @Override
    @Transactional
    public List<ResJoinTeamDTO> findAllApply(Long teamId) {
        QJoinTeam joinTeam=QJoinTeam.joinTeam;
        List<JoinTeam> fetch = jpaQueryFactory.selectFrom(joinTeam)
                .where(joinTeam.teamId.eq(teamId))
                .fetch();

        return fetch.stream().map(item ->
                ResJoinTeamDTO.builder()
                        .captionUserId(item.getCaptionUserId())
                        .isMembers(item.getIsMembers())
                        .joinUserId(item.getJoinUserId())
                        .teamId(item.getTeamId())
                        .resume(resumeService.getResume(item.getJoinUserId()))
                        .build()
        ).collect(Collectors.toList());
    }

    @Override
    public List<JoinTeam> findAllMyApply(Long userId) {
        QJoinTeam joinTeam=QJoinTeam.joinTeam;

        return  jpaQueryFactory.selectFrom(joinTeam)
                .distinct()
                .where(joinTeam.joinUserId.eq(userId))
                .fetch();



    }


    @Override
    @Transactional(isolation = REPEATABLE_READ)//读已提交级别
    public Boolean isFull(Long teamId) {

        QTeam team=QTeam.team;
        QTeamUser teamUser=QTeamUser.teamUser;

        Long exist = jpaQueryFactory.select(team.teamId).from(team).where(team.teamId.eq(teamId)).fetchOne();

        Integer need;
        Long had;
        try {
            if (exist != null) {
                need=jpaQueryFactory.select(team.teamNum)
                        .from(team)
                        .where(team.teamId.eq(teamId))
                        .fetchOne();
                had=jpaQueryFactory.select(teamUser.teamId.count())
                        .from(teamUser)
                        .where(teamUser.teamId.eq(teamId))
                        .fetchOne();
            }else {
              log.warn(teamId+"队伍不存在");
              return true;
            }
            long have;
            //计算时加锁
            synchronized (lock) {
                if (need!=null&&had!=null){
                    have = need - had;
                }else if (need==null){
                    log.warn(teamId+"招收人员没写入");
                    have=0;
                }else {
                    log.warn(teamId+"队长没写入或者其他错误");
                    have=0;
                }

            }
            return !(have > 0);
        }catch (NullPointerException e){
            return true;
        }

    }

}
